package com.rlax.framework.support.ueditor;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map;

import org.apache.commons.io.FilenameUtils;
import org.apache.commons.io.IOUtils;

import com.baidu.ueditor.define.AppInfo;
import com.baidu.ueditor.define.BaseState;
import com.baidu.ueditor.define.MultiState;
import com.baidu.ueditor.define.State;
import com.baidu.ueditor.manager.AbstractFileManager;
import com.rlax.framework.support.file.FileInfo;
import com.rlax.framework.support.file.FileManager;
import com.rlax.framework.support.file.FileResult;
import com.rlax.framework.support.file.oss.AliyunOssFileManager;

/**
 * aliyun oss 文件管理 4 Ueditor
 * @author Rlax
 *
 */
public class AliyunOssUeditorFileManager extends AbstractFileManager {

	private FileManager fileManager;
	
    public AliyunOssUeditorFileManager(String endpoint, String accessId, String accessKey, String bucket) {
    	fileManager = new AliyunOssFileManager(endpoint, accessId, accessKey, bucket);
    }
   
	private State getState(String[] keys) {
		MultiState state = new MultiState(true);
		BaseState fileState = null;

		for (String key : keys) {
			if (key == null) {
				break;
			}
			fileState = new BaseState(true);
			fileState.putInfo("url", key);
			state.addState(fileState);
		}

		return state;
	}
    
	@Override
	public State list(Map<String, Object> conf, int start) {
		String dirPath = (String) conf.get("dir");
		List<String> allowFiles = getAllowFiles(conf.get("allowFiles"));
		int count = (Integer) conf.get("count");
		
		if (dirPath.startsWith("/")) {
			dirPath = dirPath.substring(1);
		}
		
		List<String> list = new ArrayList<String>();
		
		List<FileInfo> fileList = fileManager.list(dirPath);
		for (FileInfo file : fileList) {
			if (allowFiles.contains(file.getExt())) {
				list.add("/" + file.getKey());
			}
		}
		
		Collections.reverse(list);
		State state = null;
		if (start < 0 || start > list.size()) {
			state = new MultiState(true);
		} else {
			String[] files = Arrays.copyOfRange(list.toArray(new String[]{}), start, start + count);
			state = getState(files);
		}

		state.putInfo("start", start);
		state.putInfo("total", list.size());
		return state;
	}

	@Override
	public State saveFile(byte[] data, String rootPath, String savePath) {
		FileResult result = fileManager.save(data, savePath);
		if (result.isSuccess() == false) {
			return new BaseState(false, AppInfo.IO_ERROR);
		}
		
		State state = new BaseState(true);
		state.putInfo("size", data.length);
		state.putInfo("title", getFileName(savePath));
		return state;
	}

	@Override
	public State saveFile(InputStream is, String rootPath, String savePath, long maxSize) {
		ByteArrayOutputStream output = new ByteArrayOutputStream();
		byte[] data = null;
		try {
			IOUtils.copy(is, output);
			data = output.toByteArray();
			if (data.length > maxSize) {
				return new BaseState(false, AppInfo.MAX_SIZE);
			}
			FileResult result = fileManager.save(data, savePath);
			if (result.isSuccess() == false) {
				return new BaseState(false, AppInfo.IO_ERROR);
			}
		} catch (IOException e) {	
			return new BaseState(false, AppInfo.IO_ERROR);
		} finally {
			IOUtils.closeQuietly(output);
			IOUtils.closeQuietly(is);
		}
		
		State state = new BaseState(true);
		state.putInfo("size", data.length);
		state.putInfo("title", getFileName(savePath));
		return state;
	}

	@Override
	public State saveFile(InputStream is, String rootPath, String savePath) {
		ByteArrayOutputStream output = new ByteArrayOutputStream();
		byte[] data = null;
		try {
			IOUtils.copy(is, output);
			data = output.toByteArray();
			
			FileResult result = fileManager.save(data, savePath);
			if (result.isSuccess() == false) {
				return new BaseState(false, AppInfo.IO_ERROR);
			}
		} catch (IOException e) {	
			return new BaseState(false, AppInfo.IO_ERROR);
		} finally {
			IOUtils.closeQuietly(output);
			IOUtils.closeQuietly(is);
		}
		
		State state = new BaseState(true);
		state.putInfo("size", data.length);
		state.putInfo("title", getFileName(savePath));
		return state;
	}

	private String getFileName(String savePath) {
		return FilenameUtils.getBaseName(savePath);
	}
}
